﻿/*
* Copyright 2009-2010 AKABANA.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
using System.IO;
using Akabana.Amf.IO;

namespace Akabana.Amf.Amf3.IO
{
    public static class Amf3ReaderExt
    {
        public static Amf3TypeMarker ReadTypeMarker(this AmfReader reader)
        {
            return (Amf3TypeMarker)reader.ReadByte();
        }

        public static int ReadS29(this BinaryReader reader)
        {
            int u29 = 0;
            int u29_1 = reader.ReadByte();
            int u29_2 = 0;
            int u29_3 = 0;
            int u29_4 = 0;
            int length = 1;

            if ((u29_1 & 0x80) == 0x80)
            {
                length++;
                u29_1 &= 0x7f;
                u29_2 = reader.ReadByte();

                if ((u29_2 & 0x80) == 0x80)
                {
                    length++;
                    u29_2 &= 0x7f;
                    u29_3 = reader.ReadByte();

                    if ((u29_3 & 0x80) == 0x80)
                    {
                        length++;
                        u29_3 &= 0x7f;
                        u29_4 = reader.ReadByte() & 0xff;
                    }
                }
            }

            switch (length)
            {
                case 4:
                    if ((u29_1 & 0x40) == 0x40)
                    {
                        u29 = ((u29_1 & 0x3f) << 22) | (u29_2 << 15) | (u29_3 << 8) | u29_4;
                        int negative = 0xF0 << 24;
                        u29 |= negative;
                    }
                    else
                    {
                        u29 = ((u29_1 & 0x3f) << 22) | (u29_2 << 15) | (u29_3 << 8) | u29_4;
                    }
                    break;
                case 3:
                    u29 = (u29_1 << 14) | (u29_2 << 7) | u29_3;
                    break;
                case 2:
                    u29 = (u29_1 << 7) | u29_2;
                    break;
                case 1:
                default:
                    u29 = u29_1;
                    break;

            }
            return u29;
        }

        public static int ReadU29(this BinaryReader reader)
        {

            int u29 = 0;
            int u29_1 = reader.ReadByte();
            int u29_2 = 0;
            int u29_3 = 0;
            int u29_4 = 0;
            int length = 1;

            if ((u29_1 & 0x80) == 0x80)
            {
                length++;
                u29_1 &= 0x7f;
                u29_2 = reader.ReadByte();

                if ((u29_2 & 0x80) == 0x80)
                {
                    length++;
                    u29_2 &= 0x7f;
                    u29_3 = reader.ReadByte();

                    if ((u29_3 & 0x80) == 0x80)
                    {
                        length++;
                        u29_3 &= 0x7f;
                        u29_4 = reader.ReadByte() & 0xff;
                    }
                }
            }

            switch (length)
            {
                case 4:
                    u29 = (u29_1 << 22) | (u29_2 << 15) | (u29_3 << 8) | u29_4;
                    break;
                case 3:
                    u29 = (u29_1 << 14) | (u29_2 << 7) | u29_3;
                    break;
                case 2:
                    u29 = (u29_1 << 7) | u29_2;
                    break;
                case 1:
                default:
                    u29 = u29_1;
                    break;
            }
            return u29;
        }
    }
}
